﻿#include "Application1.h"
#include <QXmlStreamReader>
#include <QFile>

typedef SER_INSTANCE (*DllFun)(SerLoad *ser);
typedef UI_INSTANCE (*DllUiFun)(QWidget *parent,ViewLoad *view);

Application1::Application1(QWidget *parent): QWidget(parent)
{
	ui.setupUi(this);	
	this->logger=new Logger(qApp->applicationDirPath()+"/Application1"+".log");
	connect(ui.btnManage,SIGNAL(clicked()),&mLifeManageDlg,SLOT(show()));
	connect(ui.btnViewLog,&QPushButton::clicked,[this](){
		QProcess::startDetached("notepad",QStringList(this->logger->path()))||
		QProcess::startDetached("explorer",QStringList(this->logger->path()));
	});
	//you can change this according to your requirements
}

Application1::~Application1()
{
	//qDeleteAll(mILoadManagerMap);
	delete logger;
	this->logger=nullptr;
}
void Application1::Start()
{
	this->Setup();
	this->readXml();
	this->loadSerDll();
	this->loadViewDll(this->ui.frame);
	mLifeManageDlg.setData(vecSerLoad,vecViewLoad,mILoadManagerMap);
}
void Application1::readXml()
{
	QFile file(qApp->applicationFilePath()+".xml");
	if (file.open(QIODevice::ReadOnly|QIODevice::Text))
	{
		QXmlStreamReader reader(&file);
		do 
		{
			reader.readNext();
			if (reader.isStartElement())
			{
				if (reader.name()==QStringLiteral("Instance"))
				{
					auto attrs = reader.attributes();
					auto name = attrs.value(QStringLiteral("name")).toString();
					auto load = attrs.value(QStringLiteral("load")).toString();
					mFlags[name]=QVariant(load).toBool();
				}
			}
		} while (!reader.atEnd());
	}
	file.close();
}
void Application1::loadSerDll()
{
	auto lambda=[this](SerLoad& serLoad)
	{
		QString comName=QString::fromStdString(serLoad.compName);//组件名
		QString instanceName=QString::fromStdString(serLoad.instanceName);//实例名
		//先判断mILoadManagerMap集合里有没有加载过dll
		ILoadManager* pSerLoadManager=nullptr;
		//如果没有
		if (!this->mILoadManagerMap.contains(comName))
		{
			pSerLoadManager = new SerLoadManager(comName,logger);//就创建一个对象，把组件dll加载进来
			mILoadManagerMap.insert(comName,pSerLoadManager);//并把该对象添加到集合里
		}
		//否则，从集合里找到dll组件
		else
		{
			pSerLoadManager=this->mILoadManagerMap.value(comName);
		}
		if (this->mFlags.value(instanceName,false))//如果需要加载实例
		{
			pSerLoadManager->Load(&serLoad);
			pSerLoadManager->Init(instanceName);
			pSerLoadManager->Active(instanceName);
		}
		else
		{
			pSerLoadManager->Load(&serLoad);
			pSerLoadManager->Init(instanceName);
		}
	};
	for_each(vecSerLoad.begin(),vecSerLoad.end(),lambda);
}
void Application1::loadViewDll(QWidget *parent)
{
	auto lambda=[this,parent](ViewLoad& viewLoad)
	{
		QString pluginName=QString::fromStdString(viewLoad.pluginName);//组件名
		QString instanceName=QString::fromStdString(viewLoad.instanceName);//实例名
		ILoadManager* pViewLoadManager=nullptr;
		if (!this->mILoadManagerMap.contains(pluginName))
		{
			pViewLoadManager = new ViewLoadManager(pluginName,parent,logger);
			mILoadManagerMap.insert(pluginName,pViewLoadManager);
		}
		else
		{
			pViewLoadManager=this->mILoadManagerMap.value(pluginName);
		}
		if (this->mFlags.value(instanceName,false))//如果需要加载实例
		{
			pViewLoadManager->Load(&viewLoad);
			pViewLoadManager->Init(instanceName);
			pViewLoadManager->Active(instanceName);
		}
		else
		{
			pViewLoadManager->Load(&viewLoad);
			pViewLoadManager->Init(instanceName);
		}
	};
	for_each(vecViewLoad.begin(),vecViewLoad.end(),lambda);
}
//应用规划后的结果
void Application1::Setup()
{

	
		SerLoad* pTransformer93=new SerLoad(93,"Transformer","Transformer3");
	
	
	
		ECOM::Base::Port* pOriginData194 = new ECOM::Base::Port(94,"OriginData1","OriginalData","publish");
		pTransformer93->vec_Ports.push_back(*pOriginData194);
	
	
		ECOM::Base::Interface* pPolarUnit196 = new ECOM::Base::Interface(96,"PolarUnit1","defaultServiceName","ADD","provide");
		pTransformer93->vec_Interfaces.push_back(*pPolarUnit196);
	
		ECOM::Base::Interface* pPolarUnit397 = new ECOM::Base::Interface(97,"PolarUnit3","PolarUnit397","MINUS","provide");
		pTransformer93->vec_Interfaces.push_back(*pPolarUnit397);
	
	
		vecSerLoad.push_back(*pTransformer93);
	
	

	
	
		ViewLoad* pNavidisplay103=new ViewLoad(103,"Navidisplay","Navidisplay5",300,100);
	
	
		ECOM::Base::Port* pTestData2104 = new ECOM::Base::Port(104,"TestData2","MyData","consume");
		pNavidisplay103->vec_Ports.push_back(*pTestData2104);
	
	
		ECOM::Base::Interface* pPolarUnit4106 = new ECOM::Base::Interface(106,"PolarUnit4","PolarUnit397","MINUS","require");
		pNavidisplay103->vec_Interfaces.push_back(*pPolarUnit4106);
	
	
	
		vecViewLoad.push_back(*pNavidisplay103);
	

}
